package com.fanben100.util;

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;

/**
 * 使用DES加密和解密的方法
 * 
 * 
 * */
public class CryptoTools {
	private final byte[] DESkey = { -111, 2, -75, 117, 67, 22, -5, -99, 62, 81,
			-50, 7, 84, 47, -128, 4, -94, -63, -80, -128, -99, -111, -108, 82 };// 设置密钥，略去
	private final byte[] DESIV = { -48, -123, -45, 64, -33, -45, 14, 93 };// 设置向量，略去

	private AlgorithmParameterSpec iv = null;// 加密算法的参数接口，IvParameterSpec是它的一个实现
	private Key key = null;

	private CryptoTools() throws InvalidKeyException, NoSuchAlgorithmException,
			InvalidKeySpecException {
		DESKeySpec keySpec = new DESKeySpec(DESkey);// 设置密钥参数
		iv = new IvParameterSpec(DESIV);// 设置向量
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 获得密钥工厂
		key = keyFactory.generateSecret(keySpec);// 得到密钥对象

	}

	public String encode(String data) throws Exception {
		Cipher enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");// 得到加密对象Cipher
		enCipher.init(Cipher.ENCRYPT_MODE, key, iv);// 设置工作模式为加密模式，给出密钥和向量
		byte[] pasByte = enCipher.doFinal(data.getBytes("utf-8"));
		BASE64Encoder base64Encoder = new BASE64Encoder();
		return base64Encoder.encode(pasByte);
	}

	public String decode(String data) throws Exception {
		Cipher deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
		deCipher.init(Cipher.DECRYPT_MODE, key, iv);
		BASE64Decoder base64Decoder = new BASE64Decoder();

		byte[] pasByte = deCipher.doFinal(base64Decoder.decodeBuffer(data));

		return new String(pasByte, "UTF-8");
	}

	private static class CryptToolsSingleHolder {
		private static CryptoTools tools = null;
		static {
			try {
				tools = new CryptoTools();
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (InvalidKeySpecException e) {
				e.printStackTrace();
			}
		}

	}

	public static CryptoTools getInstance() {
		return CryptToolsSingleHolder.tools;
	}

	public static void main(String[] args) throws Exception {
		CryptoTools criptTool = new CryptoTools();
		String encode = criptTool.encode("你好，靠");
		System.out.println("encode:" + encode);
		String decode = criptTool.decode(encode);
		System.out.println("decode:" + decode);

	}
}